import logging
import random
import uuid
from celery.result import AsyncResult
from django.utils import timezone
from rest_framework import status
from rest_framework.generics import ListAPIView, get_object_or_404
from rest_framework.response import Response
from rest_framework.views import APIView
from InterviewAgent.celery_app import app
from Resume.service.utils import upload_to_oss
from .models import Interview, Answer, GeneratedQuestion, AnswerAnalysis, Question, Report
from .service import recommend
from .service.API import ask_question_to_spark
from .service.celery.tasks import analyze_video_task, analyze_audio_task
from .service.recommend import InterviewRecommender
from .service.report import compare_two_reports
from .service.serializers import AnswerAnalysisSerializer, QuestionSerializer, ReportSerializer

logger = logging.getLogger(__name__)


class UploadInterviewVideo(APIView):
    """
    1. 前端上传面试视频（.mp4/.mov/...），保存到 OSS，并返回 oss_path
    2. 同时触发两个异步 Celery 任务：
       - analyze_video_task：做视频层面的人脸表情/姿态分析
       - analyze_audio_task：从视频里抽音频、调用阿里听悟做语音识别并提取音频特征
    """

    def post(self, request):
        user_id = request.user.get('user_id')
        interview_id = request.data.get('interview_id')
        video_file = request.FILES.get('video')

        if not (user_id and interview_id and video_file):
            return Response(
                {"error": "缺少 interview_id 或 video 文件"},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 1. 生成一个 OSS 路径，并上传文件
        ext = video_file.name.rsplit('.', 1)[-1]
        oss_path = f"videos/{user_id}/{interview_id}/{uuid.uuid4().hex}.{ext}"
        oss_url = upload_to_oss(video_file, oss_path)
        if not oss_url:
            return Response(
                {"error": "OSS 上传失败"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

        # 2. 确保 Interview 已存在并写入音视频路径
        try:
            interview = Interview.objects.get(pk=interview_id)
            interview.video_path = oss_path
            interview.save(update_fields=["video_path"])
        except Interview.DoesNotExist:
            return Response(
                {"error": f"Interview({interview_id}) 不存在"},
                status=status.HTTP_400_BAD_REQUEST
            )

        # 3. 同时触发“视频分析”和“音频分析”两个 Celery 任务
        video_task = analyze_video_task.delay(oss_path, interview_id)
        audio_task = analyze_audio_task.delay(oss_path, interview_id)

        return Response(
            {
                "data": "视频上传成功，已启动分析任务",
                "interview_id": interview_id,
                "video_task_id": video_task.id,
                "audio_task_id": audio_task.id,
                "oss_url": oss_url
            },
            status=status.HTTP_202_ACCEPTED
        )


# 查询异步任务评分进度
class TaskStatusView(APIView):
    def get(self, request):
        task_id = request.query_params.get('task_id')
        if not task_id:
            return Response({"error": "缺少 task_id 参数"}, status=400)

        res = AsyncResult(task_id, app=app)
        data = {
            "task_id": task_id,
            "status": res.status,  # PENDING, STARTED, SUCCESS, FAILURE
        }

        if res.status == "SUCCESS":
            data["result"] = res.result
        elif res.status == "FAILURE":
            data["error"] = str(res.result)

        return Response(data)


# 开启一次新的面试
class StartInterviewView(APIView):
    """
    开始一次新的面试，创建 Interview 记录并返回 interview_id
    """

    def post(self, request):
        user_id = request.user.get('user_id')
        position = request.data.get('position', '')  # 前端可选传岗位名称

        if not user_id:
            return Response({"error": "用户未登录"}, status=status.HTTP_401_UNAUTHORIZED)

        # 创建一条新的 Interview 记录
        interview = Interview.objects.create(
            user_id=user_id,
            position=position,
            start_time=timezone.now(),
            # video_path、audio_path 留空，后续上传时再填
        )

        return Response({
            "interview_id": interview.interview_id,
            "message": "面试已创建，可上传视频并启动分析"
        }, status=status.HTTP_201_CREATED)


# 异步任务处理文本、音频、视频情感分析
class EmotionAnalysisView(APIView):

    def post(self, request):
        answer_id = request.data.get('answer_id')
        generated_q_id = Answer.objects.get(answer_id=answer_id).generated_q_id
        interview_id = GeneratedQuestion.objects.get(generated_q_id=generated_q_id).interview_id
        from .service.celery.tasks import audio_emotion_analysis_task, \
            text_emotion_analysis_task, video_emotion_analysis_task
        # 同时触发“文本情感分析”和“音频情感分析”和“视频情感分析”三个 Celery 任务
        text_emotion_task = text_emotion_analysis_task.delay(answer_id, interview_id)
        audio_emotion_task = audio_emotion_analysis_task.delay(answer_id, interview_id)
        video_emotion_task = video_emotion_analysis_task.delay(answer_id, interview_id)
        return Response(
            {
                "code": 200,
                "msg": "该回答情感分析任务完成",
                "data": {
                    "interview_id": interview_id,
                    "answer_id": answer_id,
                    "text_emotion_task": text_emotion_task.id,
                    "audio_emotion_task": audio_emotion_task.id,
                    "video_emotion_task": video_emotion_task.id, }}
        )


class uploadAnswerVideoView(APIView):
    def post(self, request):
        answer_id = request.data.get('answer_id')
        generated_q_id = Answer.objects.get(answer_id=answer_id).generated_q_id
        interview_id = GeneratedQuestion.objects.get(generated_q_id=generated_q_id).interview_id
        user_id = request.user.get('user_id')
        video_file = request.FILES.get('video')
        print(video_file)
        ext = video_file.name.rsplit('.', 1)[-1]
        oss_path = f"videos/{user_id}/{interview_id}/{uuid.uuid4().hex}.{ext}"
        oss_url = upload_to_oss(video_file, oss_path)
        answer = Answer.objects.get(answer_id=answer_id)
        answer.video_path = oss_url
        answer.save()
        return Response({"code": 200, "msg": "上传回答片段成功", "oss_path": oss_url})


class getQuestionListView(ListAPIView):
    serializer_class = QuestionSerializer

    def get_queryset(self):
        # 获取查询参数
        role = self.request.query_params.get('role')
        question_type = self.request.query_params.get('question_type')
        difficulty = self.request.query_params.get('difficulty')
        keyword = self.request.query_params.get('keyword')

        # 获取最新的interview_id
        user_id = self.request.user.get('user_id')
        interview = Interview.objects.filter(user_id=user_id).order_by('-start_time').first()
        queryset = Question.objects.all()
        if role:
            queryset = queryset.filter(role__iexact=role)
        if question_type:
            queryset = queryset.filter(question_type__iexact=question_type)
        if difficulty:
            queryset = queryset.filter(difficulty__iexact=difficulty)
        if keyword:
            queryset = queryset.filter(content__icontains=keyword)
        # 获取推荐题目
        if interview:
            report = Report.objects.filter(interview_id=interview.interview_id).first()
            if report:
                recommender = InterviewRecommender(report, user_id)
                queryset = recommender.recommend_questions(queryset)
        print(queryset)
        print(type(queryset))
        ran = self.request.query_params.get('random')
        if ran == '0':
            return queryset
        else:
            queryset = list(queryset)  # 转成 list
            random.shuffle(queryset)
            return queryset

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        print(queryset)
        user_id = self.request.user.get('user_id')
        interview = Interview.objects.filter(user_id=user_id).order_by('-start_time').first()
        tags_targeted = []

        # 获取弱点标签
        if interview:
            report = Report.objects.filter(interview_id=interview.interview_id).first()
            if report:
                recommender = InterviewRecommender(report, user_id)
                tags_targeted = recommender.extract_weak_dimensions()

        # 分页
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            response_data = {
                "recommended_questions": serializer.data,
                "tags_targeted": tags_targeted,
                "from": "personalized_feedback"
            }
            return self.get_paginated_response(response_data)
        # 无分页时的响应
        serializer = self.get_serializer(queryset, many=True)
        return Response({
            "recommended_questions": serializer.data,
            "tags_targeted": tags_targeted,
            "from": "personalized_feedback"
        })


class postAnswerView(APIView):
    def post(self, request):
        question_id = request.data.get('question_id')
        answer = request.data.get('answer')
        reference_answer = Question.objects.get(question_id=question_id).reference_answer
        text = f"这是参考答案:‘{reference_answer}’,这是提交的答案:‘{answer}’,请给出评分并说说提交答案的不足和需要改进的地方"
        response = ask_question_to_spark(text)
        return Response({"code": 200, "msg": "答案不足与建议已给出", "data": response})


class ReportCompareAPIView(APIView):
    """
    GET /api/compare_reports/?interview1=<id1>&interview2=<id2>
    调用 compare_two_reports 返回结构化 diff 与 AI 解读。
    """
    def get(self, request, *args, **kwargs):
        # 1. 解析参数
        i1 = request.query_params.get('interview1')
        i2 = request.query_params.get('interview2')
        if not i1 or not i2:
            return Response(
                {"detail": "请提供 interview1 和 interview2 参数"},
                status=status.HTTP_400_BAD_REQUEST
            )
        # 2. 取出两个报告的 metrics
        rpt1 = get_object_or_404(Report, interview_id=i1)
        rpt2 = get_object_or_404(Report, interview_id=i2)
        r1 = rpt1.metrics or {}
        r2 = rpt2.metrics or {}

        # 3. 调用对比函数
        comparison = compare_two_reports(r1, r2)

        # 4. 返回结果
        return Response(
            comparison,
            status=status.HTTP_200_OK
        )


class getReportByInterview(APIView):
    def post(self, request):
        interview_id = request.data.get('interview_id')
        report = Report.objects.filter(interview_id=interview_id).first()
        if not report:
            return Response(
                {"detail": "不存在对应interview生成的报告"},
                status=status.HTTP_400_BAD_REQUEST
            )
        serializer = ReportSerializer(report)
        return Response({'code': 200,'msg': 'success', 'data': serializer.data})
